package com.paas.form.service.impl;


import com.alibaba.fastjson.JSON;
import com.bpm.feign.model.BpmDeCategoryEntity;
import com.bpm.feign.model.ProcessCmd;
import com.bpm.feign.service.IBpmDeCategoryService;
import com.bpm.feign.service.IBpmProcessInstanceService;
import com.paas.common.model.RestResponse;
import com.paas.common.util.BeanUtil;
import com.paas.common.util.ListUtil;
import com.paas.common.util.StringUtil;
import com.paas.common.util.UniqueIdUtil;
import com.paas.form.constant.FormConstant;
import com.paas.form.dto.FormInfoChangeDto;
import com.paas.form.entity.FormViewChangeInfoDetailEntity;
import com.paas.form.entity.FormViewChangeInfoEntity;
import com.paas.form.entity.FormDefinitionEntity;
import com.paas.form.entity.FormViewPubEntity;
import com.paas.form.service.*;
import com.paas.form.vo.ChangeField;
import com.paas.form.vo.FormViewChangeInfoDetailVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 表单变更服务实现类
 */
@Slf4j
@Service("formChangeService")
public class FormChangeServiceImpl extends AbsChangeService implements IFormChangeService {

    public static final String CHANGE_FORM_INFO ="form_info";

    @Autowired
    private IFormViewChangeInfoService formViewChangeInfoService;

    @Autowired
    private IFormViewChangeInfoDetailService formViewChangeInfoDetailService;

    @Autowired
    private IFormDefinitionService formViewPublishService;

    @Autowired
    public IBpmProcessInstanceService bpmProcessInstanceService;

    //流程分类查询
    @Autowired
    public IBpmDeCategoryService bpmDeCategoryService;

    //定版视图
    @Autowired
    public IFormViewPubService formViewPubService;

    /**
     * 表单基本信息变更
     * @param formInfoChangeDto
     * @return
     */
    @Override
    public RestResponse saveFormChangeInfo(FormInfoChangeDto<ProcessCmd> formInfoChangeDto){
        //定义变更表单信息
        FormDefinitionEntity formViewPublishEntity = formInfoChangeDto.getFormViewPublishEntity();
        if(BeanUtil.isEmpty(formViewPublishEntity) || StringUtil.isEmpty(formViewPublishEntity.getId())){
            return RestResponse.error("请求参数错误，表单对象为空");
        }
        /**
         * 检查是否存在变更中的表单信息
         */
        boolean flag;
        if(StringUtil.isEmpty(formInfoChangeDto.getLogId())){
            flag = formViewChangeInfoService.isExistsChange(FormConstant.ChangeTypeEnum.VIEW_CHANGE_TYPE.getType(), formViewPublishEntity.getId());
        }else{
            flag = formViewChangeInfoService.isExistsChange(FormConstant.ChangeTypeEnum.VIEW_CHANGE_TYPE.getType(), formViewPublishEntity.getId(),formInfoChangeDto.getLogId());
        }
        if(flag){
            return RestResponse.error("当前表单存在审批中的数据，请先审批之前的数据再发起变更！");
        }
        //查询变更前的表单信息
        FormDefinitionEntity exsistsFormInfo = formViewPublishService.getById(formViewPublishEntity.getId());

        //记录变更明细集合
        List<FormViewChangeInfoDetailEntity> detailList = new ArrayList<>();
        try {
            formViewPublishEntity.setPublishApprovalStatus(FormDefinitionEntity.BIZ_STATUS_CHANGEING);
            compareChangeInfo(exsistsFormInfo, formViewPublishEntity, formViewPublishEntity.getId(),CHANGE_FORM_INFO,detailList);
        } catch (Exception e) {
            throw new RuntimeException("设置表单变更项失败!"+e.getMessage());
        }
        //变更项为空是直接返回
        if(detailList.size() ==0){
            return RestResponse.error("没有存在变更项，不允许提交！");
        }
        FormViewChangeInfoEntity formViewChangeInfoEntity = new FormViewChangeInfoEntity();
        //驳回修改时 处理之前保存的业务数据
        if(StringUtil.isNotEmpty(formInfoChangeDto.getLogId())){
            //删除上次的变更明细
            formViewChangeInfoDetailService.deleteByChangeId(formInfoChangeDto.getLogId());
        }
        boolean isAddFlag = false;
        //设置变更主表基本信息
        if(StringUtil.isEmpty(formInfoChangeDto.getLogId())){
            formViewChangeInfoEntity.setId(UniqueIdUtil.getGuid());
            formViewChangeInfoEntity.setName(formViewPublishEntity.getName()+"变更");
            formViewChangeInfoEntity.setLinkId(formViewPublishEntity.getId());
            formViewChangeInfoEntity.setOperationStatus(FormConstant.CHANGE_OPERATION_NOAPPROVE);
            formViewChangeInfoEntity.setType(FormConstant.ChangeTypeEnum.VIEW_CHANGE_TYPE.getType());
            formViewChangeInfoEntity.setRemark(formInfoChangeDto.getRemark());
            formViewChangeInfoEntity.setChangeCount(String.valueOf(detailList.size()));
            formViewChangeInfoEntity.setStatus("1");
            //保存数据
            formViewChangeInfoService.insert(formViewChangeInfoEntity);
            isAddFlag = true;
        }else{
            //更新日志主表信息
            formViewChangeInfoEntity.setId(formInfoChangeDto.getLogId());
            formViewChangeInfoEntity.setOperationStatus(FormConstant.CHANGE_OPERATION_NOAPPROVE);
            formViewChangeInfoEntity.setRemark(formInfoChangeDto.getRemark());
            formViewChangeInfoEntity.setChangeCount(String.valueOf(detailList.size()));
            //更新数据
            formViewChangeInfoService.updateById(formViewChangeInfoEntity);
        }
        //变更明细补充字段
        for(FormViewChangeInfoDetailEntity temp:detailList){
            temp.setChangeInfoId(formViewChangeInfoEntity.getId());
        }
        //保存变更明细数据
        formViewChangeInfoDetailService.insertBatch(detailList);
        //修改表单表主数据状态
        FormDefinitionEntity updateForm = new FormDefinitionEntity();
        updateForm.setId(exsistsFormInfo.getId());
        updateForm.setPublishApprovalStatus(FormDefinitionEntity.BIZ_STATUS_CHANGEING);
        formViewPublishService.updateById(updateForm);

        // 定义流程
        ProcessCmd processCmd = formInfoChangeDto.getProcessCmd();
        if (BeanUtil.isNotEmpty(processCmd)) {
            if(isAddFlag){
                processCmd.setBusinessKey(formViewChangeInfoEntity.getId());
                processCmd.setData(JSON.toJSONString(formViewPublishEntity));
                processCmd.setAppId(formInfoChangeDto.getAppId());
                bpmProcessInstanceService.startProcessInstance(processCmd);
            }else{
                processCmd.setToEditor(true);
                processCmd.setData(JSON.toJSONString(formViewPublishEntity));
                bpmProcessInstanceService.completeSubmitTask(processCmd);
            }
        }
        return RestResponse.success("保存成功");
    }

    @Override
    public FormInfoChangeDto getFormChangeDtoById(String logId){
        //空值判断
        if(StringUtil.isEmpty(logId)){
            return null;
        }
        FormInfoChangeDto formInfoChangeDto = new FormInfoChangeDto();
        //数据查询
        FormViewChangeInfoEntity formViewChangeInfoEntity = formViewChangeInfoService.getById(logId);
        if(BeanUtil.isEmpty(formViewChangeInfoEntity)){
            log.error("找不到对应的变更记录");
            return formInfoChangeDto;
        }
        //查询表单信息,根据业务id
        FormDefinitionEntity formDefinitionEntity = formViewPublishService.getById(formViewChangeInfoEntity.getLinkId());
        if(BeanUtil.isEmpty(formDefinitionEntity)){
            log.error("["+formViewChangeInfoEntity.getLinkId()+"],找不到相应的表单信息");
            return formInfoChangeDto;
        }
        //定版视图查询
        if(StringUtil.isNotEmpty(formDefinitionEntity.getViewId())){
            FormViewPubEntity formViewPubEntity = formViewPubService.getById(formDefinitionEntity.getViewId());
            formInfoChangeDto.setFormViewPubEntity(formViewPubEntity);
        }

        //定义key为流程分类id,value为流程分类对象
        Map<String, BpmDeCategoryEntity> bpmDeCategoryMap = new HashMap<String,BpmDeCategoryEntity>();
        /**
         * 处理流程分类名称
         */
        List<String> processIds = new ArrayList<>();

        /**
         * 查询变更明细
         */
        List<FormViewChangeInfoDetailEntity> viewChangeInfoDetailList = formViewChangeInfoDetailService.getListByChangeId(logId);
        List<FormViewChangeInfoDetailVo> showLogDetails = new ArrayList<>();
        if(BeanUtil.isNotEmpty(viewChangeInfoDetailList)){
            /**
             * 定义流程分类id集合
             */
            List<String> categeyFields = new ArrayList<>();
            categeyFields.add("applyProcess");
            categeyFields.add("changeProcess");
            categeyFields.add("enableProcess");
            categeyFields.add("stopProcess");
            categeyFields.add("deleteProcess");

            for(FormViewChangeInfoDetailEntity temp:viewChangeInfoDetailList){
                //再次确认一下表单基本信息主键 与变更明细表linkId
                if(formDefinitionEntity.getId().equals(temp.getLinkId())){
                    //设置最新值
                    BeanUtil.setProperty(formDefinitionEntity, temp.getFieldCode(), temp.getNewValue());
                    if(categeyFields.contains(temp.getFieldCode())){
                        ListUtil.addUniqueValue(processIds,temp.getOldValue());
                        ListUtil.addUniqueValue(processIds,temp.getNewValue());
                    }
                }
            }
            //添加流程分类id至集合
            if(StringUtil.isNotEmpty(formDefinitionEntity.getApplyProcess())){
                ListUtil.addUniqueValue(processIds,formDefinitionEntity.getApplyProcess());
            }
            if(StringUtil.isNotEmpty(formDefinitionEntity.getChangeProcess())){
                ListUtil.addUniqueValue(processIds,formDefinitionEntity.getChangeProcess());
            }
            if(StringUtil.isNotEmpty(formDefinitionEntity.getDeleteProcess())){
                ListUtil.addUniqueValue(processIds,formDefinitionEntity.getDeleteProcess());
            }
            if(StringUtil.isNotEmpty(formDefinitionEntity.getEnableProcess())){
                ListUtil.addUniqueValue(processIds,formDefinitionEntity.getEnableProcess());
            }
            if(StringUtil.isNotEmpty(formDefinitionEntity.getStopProcess())){
                ListUtil.addUniqueValue(processIds,formDefinitionEntity.getStopProcess());
            }
            if(BeanUtil.isNotEmpty(processIds)){
                List<BpmDeCategoryEntity> bpmDeCategoryList = bpmDeCategoryService.queryBatchByIds(processIds);
                if(bpmDeCategoryList!=null){
                    bpmDeCategoryMap = bpmDeCategoryList.stream().collect(Collectors.toMap(BpmDeCategoryEntity::getId, item ->item));
                }
            }

            FormViewChangeInfoDetailVo showDetailVo = null;
            for (FormViewChangeInfoDetailEntity temp : viewChangeInfoDetailList) {
                //数据状态不显示
                if("publishApprovalStatus".equals(temp.getFieldCode())){
                    continue;
                }
                showDetailVo = new FormViewChangeInfoDetailVo();
                BeanUtil.copyProperties(showDetailVo,temp);
                String showDetailOldName = temp.getOldValue();
                String showDetailNewName = temp.getNewValue();
                /**
                 * 变更 旧值、新值名称显示处理。流程分类id需要转换成名称
                 * 变更的旧值新值需要显示人员的名称,方便查看
                 */
                if("isProcess".equals(temp.getFieldCode())){
                    if(StringUtil.isNotEmpty(temp.getOldValue())){
                        showDetailOldName ="1".equals(temp.getOldValue())?"是":"否";
                    }
                    if(StringUtil.isNotEmpty(temp.getNewValue())){
                       showDetailNewName ="1".equals(temp.getNewValue())?"是":"否";
                    }
                }else if(categeyFields.contains(temp.getFieldCode())){
                    //流程分类map不为空
                    if(bpmDeCategoryMap!=null){
                        if(StringUtil.isNotEmpty(temp.getOldValue()) && bpmDeCategoryMap.containsKey(temp.getOldValue())){
                            showDetailOldName = bpmDeCategoryMap.get(temp.getOldValue()).getCatgName();
                        }
                        if(StringUtil.isNotEmpty(temp.getNewValue()) && bpmDeCategoryMap.containsKey(temp.getNewValue())){
                            showDetailNewName = bpmDeCategoryMap.get(temp.getNewValue()).getCatgName();
                        }
                    }
                } else{
                    //其它不处理
                }
                showDetailVo.setShowDetailOldName(showDetailOldName);
                showDetailVo.setShowDetailNewName(showDetailNewName);
                showLogDetails.add(showDetailVo);
            }

            if(BeanUtil.isNotEmpty(processIds)){
                List<BpmDeCategoryEntity> bpmDeCategoryList = bpmDeCategoryService.queryBatchByIds(processIds);
                if(bpmDeCategoryList!=null){
                    bpmDeCategoryMap = bpmDeCategoryList.stream().collect(Collectors.toMap(BpmDeCategoryEntity::getId, item ->item));
                }
            }

        }

        if(bpmDeCategoryMap!=null){
            //设置开启流程分类名称
            if(bpmDeCategoryMap.containsKey(formDefinitionEntity.getApplyProcess())){
                formDefinitionEntity.setApplyProcessName(bpmDeCategoryMap.get(formDefinitionEntity.getApplyProcess()).getCatgName());
            }
            if(bpmDeCategoryMap.containsKey(formDefinitionEntity.getChangeProcess())){
                formDefinitionEntity.setChangeProcessName(bpmDeCategoryMap.get(formDefinitionEntity.getChangeProcess()).getCatgName());
            }

            if(bpmDeCategoryMap.containsKey(formDefinitionEntity.getDeleteProcess())){
                formDefinitionEntity.setDeleteProcessName(bpmDeCategoryMap.get(formDefinitionEntity.getDeleteProcess()).getCatgName());
            }

            if(bpmDeCategoryMap.containsKey(formDefinitionEntity.getStopProcess())){
                formDefinitionEntity.setStopProcessName(bpmDeCategoryMap.get(formDefinitionEntity.getStopProcess()).getCatgName());
            }

            if(bpmDeCategoryMap.containsKey(formDefinitionEntity.getEnableProcess())){
                formDefinitionEntity.setEnableProcessName(bpmDeCategoryMap.get(formDefinitionEntity.getEnableProcess()).getCatgName());
            }
        }
        formInfoChangeDto.setLogId(formViewChangeInfoEntity.getId());
        formInfoChangeDto.setRemark(formViewChangeInfoEntity.getRemark());
        formInfoChangeDto.setFormViewPublishEntity(formDefinitionEntity);
        formInfoChangeDto.setShowLogDetails(showLogDetails);
        return formInfoChangeDto;
    }

    /**
     * 反对视图变更，更新主表状态即可
     * @param changeId
     * @return
     */
    @Override
    public RestResponse opposeFormChange(String changeId){
        //数据查询
        FormViewChangeInfoEntity formViewChangeInfoEntity = formViewChangeInfoService.getById(changeId);
        if(BeanUtil.isEmpty(formViewChangeInfoEntity)){
            return RestResponse.error("["+changeId+"]找不到关联的变更日志记录，请检查请求参数");
        }
        //已经审批通过的数据，不能更新
        if(FormConstant.CHANGE_OPERATION_SUCCESS.equals(formViewChangeInfoEntity.getOperationStatus())){
            return RestResponse.error("["+changeId+"]当前业务数据状态已经处于审核通过状态，不允许执行反对事件");
        }
        if(FormConstant.CHANGE_OPERATION_CANCEL.equals(formViewChangeInfoEntity.getOperationStatus())){
            return RestResponse.error("["+changeId+"]删除状态的业务数据，不允许重复执行删除事件");
        }
        //设置状态
        formViewChangeInfoEntity.setOperationStatus(FormConstant.CHANGE_OPERATION_CANCEL);
        formViewChangeInfoService.updateById(formViewChangeInfoEntity); //更新变更主表

        /**
         * 根据变更明细回滚表单状态
         */
        FormDefinitionEntity updateForm = new FormDefinitionEntity();
        updateForm.setId(formViewChangeInfoEntity.getLinkId());

        //查询变更明细数据
        List<FormViewChangeInfoDetailEntity> viewChangeInfoDetailList = formViewChangeInfoDetailService.getListByChangeId(changeId);
        if(BeanUtil.isNotEmpty(viewChangeInfoDetailList)){
            for(FormViewChangeInfoDetailEntity temp:viewChangeInfoDetailList){
                if("publishApprovalStatus".equals(temp.getFieldCode())){
                    //设置最新值
                    BeanUtil.setProperty(updateForm, temp.getFieldCode(), temp.getOldValue());
                    //更新表单数据
                    formViewPublishService.updateById(updateForm);
                    break;
                }
            }
        }
        return RestResponse.success("执行成功");
    }

    @Override
    public RestResponse approvalFormChange(String changeId){
        //数据查询
        FormViewChangeInfoEntity viewChangeInfoEntity = formViewChangeInfoService.getById(changeId);
        if(BeanUtil.isEmpty(viewChangeInfoEntity)){
            return RestResponse.error("["+changeId+"]找不到关联的变更日志记录，请检查请求参数");
        }
        //已经审批通过的数据，不能更新
        if(FormConstant.CHANGE_OPERATION_SUCCESS.equals(viewChangeInfoEntity.getOperationStatus())){
            return RestResponse.error("["+changeId+"]当前业务数据状态已经处于审核通过状态，不允许重复执行同意事件");
        }
        if(FormConstant.CHANGE_OPERATION_CANCEL.equals(viewChangeInfoEntity.getOperationStatus())){
            return RestResponse.error("["+changeId+"]删除状态的业务数据，不允许执行同意事件");
        }

        //查询表单信息,根据业务id
        FormDefinitionEntity formViewPublishEntity = formViewPublishService.getById(viewChangeInfoEntity.getLinkId());
        if(BeanUtil.isEmpty(formViewPublishEntity)){
            log.error("["+viewChangeInfoEntity.getLinkId()+"],找不到相应的视图信息");
            return RestResponse.error("["+changeId+"]关联表单不存在");
        }
        //查询变更明细数据
        List<FormViewChangeInfoDetailEntity> viewChangeInfoDetailList = formViewChangeInfoDetailService.getListByChangeId(changeId);
        if(BeanUtil.isNotEmpty(viewChangeInfoDetailList)){
            for(FormViewChangeInfoDetailEntity temp:viewChangeInfoDetailList){
                if(formViewPublishEntity.getId().equals(temp.getLinkId())){
                    //数据状态特殊处理一下
                    if("publishApprovalStatus".equals(temp.getFieldCode())){
                        //设置最新值
                        BeanUtil.setProperty(formViewPublishEntity, temp.getFieldCode(), temp.getOldValue());
                        break;
                    }else{
                        //设置最新值
                        BeanUtil.setProperty(formViewPublishEntity, temp.getFieldCode(), temp.getNewValue());
                    }
                }
            }
            //更新表单数据
            formViewPublishService.updateById(formViewPublishEntity);
        }
        //设置状态
        viewChangeInfoEntity.setOperationStatus(FormConstant.CHANGE_OPERATION_SUCCESS);
        formViewChangeInfoService.updateById(viewChangeInfoEntity); //更新变更主表状态
        return RestResponse.success("执行成功");
    }

    @Override
    public Map<String, List<ChangeField>> getViewChangeFieldConfig() {
        Map<String,List<ChangeField>> formChangeFieldConfigMap = new HashMap<String,List<ChangeField>>();
        List<ChangeField> formChangeFields = new ArrayList<>();

        formChangeFields.add(new ChangeField("columnsNumber","表单分栏数"));
        formChangeFields.add(new ChangeField("isProcess","是否开启流程"));
        formChangeFields.add(new ChangeField("applyProcess","申请流程"));
        formChangeFields.add(new ChangeField("changeProcess","变更流程"));
        formChangeFields.add(new ChangeField("enableProcess","启用流程"));
        formChangeFields.add(new ChangeField("stopProcess","停用流程"));
        formChangeFields.add(new ChangeField("deleteProcess","删除流程"));
        formChangeFields.add(new ChangeField("remark","描述"));
        formChangeFields.add(new ChangeField("publishApprovalStatus","数据状态"));
        formChangeFieldConfigMap.put(CHANGE_FORM_INFO,formChangeFields);
        return formChangeFieldConfigMap;
    }
}
